package com.changgou.seckill.controller;

import com.changgou.entity.Constants;
import com.changgou.entity.Result;
import com.changgou.entity.StatusCode;
import com.changgou.seckill.feign.SeckillOrderFeign;
import com.changgou.seckill.util.CookieUtil;
import com.changgou.util.RandomUtil;
import com.netflix.discovery.converters.Auto;
import com.sun.xml.internal.fastinfoset.algorithm.FloatEncodingAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 秒杀下单业务controller
 */
@RestController
@RequestMapping("/wseckillorder")
public class WebSeckillOrderController {


    @Autowired
    private HttpServletRequest request;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillOrderFeign seckillOrderFeign;

    /**
     * 生成页面令牌返回给页面
     * @return
     */
    @GetMapping("/getToken")
    public String getToken() {

        //1. 获取用户浏览器cookie中的短令牌jti
        Map<String, String> cookieMap = CookieUtil.readCookie(request, "uid");
        String jti = cookieMap.get("uid");
        if (StringUtils.isEmpty(jti)) {
            throw new RuntimeException("您没有登录不允许下单!");
        }

        //2. 生成一个随机字符串作为页面令牌
        String randomStr = RandomUtil.getRandomString();
        //3. jti短令牌作为key, 页面令牌作为value存入redis中, 生存时间3-5秒
        redisTemplate.boundValueOps(Constants.PAGE_TOKEN + jti).set(randomStr, 5, TimeUnit.SECONDS);

        //4. 将页面令牌返回给页面
        return randomStr;
    }


    /**
     * 秒杀下单
     * @param time  下单的秒杀时间场次
     * @param id    下单的商品id
     * @param token 页面令牌
     */
    @GetMapping("/add")
    public Result add(@RequestParam(value = "time") String time, @RequestParam(value = "id")Long id, @RequestParam(value = "token")String token) {
        //1. 判断token页面令牌如果为空不允许下单
        if (StringUtils.isEmpty(token)) {
            return  new Result(false, StatusCode.ERROR, "页面令牌为空不允许下单");
        }
        //2. 从浏览器cookie中获取jti短令牌, 获取不到不允许下单
        Map<String, String> cookieMap = CookieUtil.readCookie(request, "uid");
        String jti = cookieMap.get("uid");
        if (StringUtils.isEmpty(jti)) {
            return new Result(false, StatusCode.ERROR, "您没有登录不允许下单!");
        }

        //3. 根据jti短令牌到redis中获取Redis中的页面令牌, 获取不到不允许下单
        String redisToken = (String)redisTemplate.boundValueOps(Constants.PAGE_TOKEN + jti).get();
        if (StringUtils.isEmpty(redisToken)) {
            return new Result(false, StatusCode.ERROR, "页面令牌超时不允许下单");
        }

        //4. 判断redis中的页面令牌, 和消费者页面传入进来的页面令牌对比, 不一致不允许下单
        if (token.equals(redisToken)) {
            //5. 调用feign秒杀业务微服务的下单接口
            Boolean flag = seckillOrderFeign.add(time, id);
            if (flag) {
                return new Result(true, StatusCode.OK, "秒杀下单成功");
            } else {
                return new Result(false, StatusCode.ERROR, "秒杀下单失败");
            }
        }
        //6. 返回
        return new Result(false, StatusCode.ERROR, "异常, 不允许下单");
    }
}
